package com.wingsboat.sort;


import com.wingsboat.DefaultFilterChain;
import com.wingsboat.annotation.FilterOrder;
import com.wingsboat.interfaces.FilterChain;

/**
 * @author wangzhong
 * @desc
 */
public class FilterChainMergeSort implements FilterChainSort{
    /**
     * 过滤器链排序实现
     *
     * @param headNode 头节点（第一个节点，不是虚拟表头）
     * @return
     */
    @Override
    public FilterChain sort(FilterChain headNode){
        if(null == headNode || null == headNode.getNextFilterChain()){
            return headNode;
        }
        // 快慢指针
        FilterChain fast = headNode.getNextFilterChain();
        FilterChain slow = headNode;
        while (fast != null && fast.getNextFilterChain() != null) {
            slow = slow.getNextFilterChain();
            fast = fast.getNextFilterChain().getNextFilterChain();
        }
        //断链
        FilterChain tmp = slow.getNextFilterChain();
        slow.setNextFilterChain(null);


        //递归调用
        FilterChain left = sort(headNode);
        FilterChain right = sort(tmp);

        //建立虚拟表头
        FilterChain dummyHead = new DefaultFilterChain(null,null);
        FilterChain res = dummyHead;

        //合并
        while (left != null && right != null) {
            if(compareFilterOrder(left,right)==-1){
                dummyHead.setNextFilterChain(left);
                left = left.getNextFilterChain();
            }else{
                dummyHead.setNextFilterChain(right);
                right = right.getNextFilterChain();
            }
            dummyHead = dummyHead.getNextFilterChain();
        }
        dummyHead.setNextFilterChain(left != null ? left : right);
        return res.getNextFilterChain();
    }


    int compareFilterOrder(FilterChain left,FilterChain right){
        int leftValue = Integer.MAX_VALUE;
        int rightValue = Integer.MAX_VALUE;
        if(null != left.getFilter() && null != left.getFilter().getClass().getAnnotation(FilterOrder.class)){
            leftValue = left.getFilter().getClass().getAnnotation(FilterOrder.class).value();
        }
        if(null != right.getFilter() && null != right.getFilter().getClass().getAnnotation(FilterOrder.class)){
            rightValue = right.getFilter().getClass().getAnnotation(FilterOrder.class).value();
        }
        if(leftValue>rightValue){
            return 1;
        }
        if(leftValue<rightValue){
            return -1;
        }
        return 0;
    }
}
